package com.hd.quartz.aspect;

import com.google.gson.Gson;
import com.hd.quartz.annotation.SysLog;
import com.hd.quartz.entity.SysLogEntity;
import com.hd.quartz.service.SysLogService;
import com.hd.quartz.util.HttpContextUtils;
import com.hd.quartz.util.IPUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

/**
 * <h3>partitionjob</h3>
 * <p>SysLogAspect</p>
 * 日志切面
 *
 * @author : hduong
 * @version : 1.0
 * @date : 2020-09-15 11:14
 **/
@Order
@Aspect
@Component
@Slf4j
public class SysLogAspect {

    @Autowired
    private SysLogService sysLogService;

    /**
     * 切面 定义
     */
    @Pointcut("@annotation(com.hd.quartz.annotation.SysLog)")
    public void logPointCut() {

    }

    /**
     * 环绕切面 :
     *
     * @return
     */
    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //1: 记录执行时间
        //2: 执行方法
        //3: 记录执行日志
        long begin = System.currentTimeMillis();

        Object object = proceedingJoinPoint.proceed();

        long end = System.currentTimeMillis();
        long times = end - begin;

        save(proceedingJoinPoint, times);

        return object;
    }

    private void save(ProceedingJoinPoint proceedingJoinPoint, long times) {
        //1: 切面连接点 : 方法签名 -> 获得方法 -> 获取方法的参数 -> 获取类名 -> 获取方法名
        //2: 根据方法可以解析方法上面的注解
        //3: 方法 + 类 + 参数 + 时间 + ip
        //4: 获取用户名
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();
        SysLog annotation = method.getAnnotation(SysLog.class);
        SysLogEntity sysLogEntity = new SysLogEntity();
        if (annotation != null) {
            sysLogEntity.setOperation(annotation.value());
        }
        //请求的方法名 : 获取目标 请求类的 类名
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        String methodName2 = method.getName();
        System.out.println("signature获取方法名: " + methodName);
        System.out.println("signature获取method然后获取方法名: " + methodName2);
        sysLogEntity.setMethod(className + "." + methodName + "()");
        //请求的参数
        Object[] args = proceedingJoinPoint.getArgs();
        try {
            String params = new Gson().toJson(args[0]);
            sysLogEntity.setParams(params);
        } catch (Exception e) {

        }
        //获取request
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();

        //设置IP地址
        sysLogEntity.setIp(IPUtils.getIpAddr(request));
        //用户名
        sysLogEntity.setUsername("todo");
        sysLogEntity.setTime(times);
        sysLogEntity.setCreateDate(new Date());
        //保存系统日志
        try {
            sysLogService.save(sysLogEntity);
        } catch (Exception e) {
            log.error("保存日志失败: ", e);
        }
    }


}
